home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / rose_nos / lapb.c < prev    next >
Text File  |  1992-02-25  |  21KB  |  881 lines

  1. /* Link Access Procedures Balanced (LAPB), the upper sublayer of
  2.  * AX.25 Level 2.
  3.  * Copyright 1991 Phil Karn, KA9Q
  4.  *
  5.  * K5JB ROSE Support added
  6.  */
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "ip.h"
  13. #include "netrom.h"
  14. #include "config.h"
  15.  
  16. #ifdef ROSE
  17. #include "cmdparse.h"
  18.  
  19. /* ROSE neighbor table structure */
  20. typedef struct {
  21.     char roscall[AXALEN];    /* call of neighbor rose in header fmt */
  22.     char ipcall[AXALEN];    /* other IP station's ax25 call */
  23. } rosetab;
  24.  
  25. #ifndef TRUE
  26. #define TRUE 1
  27. #define FALSE 0
  28. #endif
  29.  
  30. #define ROSENUMCKTS    10    /* number of ROSE circuits permitted */
  31.  
  32. rosetab    rose_table[ROSENUMCKTS];
  33. int rosenbr_nr = 0;
  34. int rose_enable = FALSE;
  35. #endif /* ROSE */
  36.  
  37. static void handleit __ARGS((struct ax25_cb *axp,int pid,struct mbuf *bp));
  38. static void procdata __ARGS((struct ax25_cb *axp,struct mbuf *bp));
  39. static int ackours __ARGS((struct ax25_cb *axp,int16 n));
  40. static void clr_ex __ARGS((struct ax25_cb *axp));
  41. static void enq_resp __ARGS((struct ax25_cb *axp));
  42. static void inv_rex __ARGS((struct ax25_cb *axp));
  43.  
  44. /* Process incoming frames */
  45. int
  46. lapb_input(axp,cmdrsp,bp)
  47. struct ax25_cb *axp;        /* Link control structure */
  48. int cmdrsp;            /* Command/response flag */
  49. struct mbuf *bp;        /* Rest of frame, starting with ctl */
  50. {
  51.     int control;
  52.     int class;        /* General class (I/S/U) of frame */
  53.     int16 type;        /* Specific type (I/RR/RNR/etc) of frame */
  54.     char pf;        /* extracted poll/final bit */
  55.     char poll = 0;
  56.     char final = 0;
  57.     int16 nr;        /* ACK number of incoming frame */
  58.     int16 ns;        /* Seq number of incoming frame */
  59.     int16 tmp;
  60.  
  61.     if(bp == NULLBUF || axp == NULLAX25){
  62.         free_p(bp);
  63.         return -1;
  64.     }
  65.  
  66.     /* Extract the various parts of the control field for easy use */
  67.     if((control = PULLCHAR(&bp)) == -1){
  68.         free_p(bp);    /* Probably not necessary */
  69.         return -1;
  70.     }
  71.     type = ftype(control);
  72.     class = type & 0x3;
  73.     pf = control & PF;
  74.     /* Check for polls and finals */
  75.     if(pf){
  76.         switch(cmdrsp){
  77.         case LAPB_COMMAND:
  78.             poll = YES;
  79.             break;
  80.         case LAPB_RESPONSE:
  81.             final = YES;
  82.             break;
  83.         }
  84.     }
  85.     /* Extract sequence numbers, if present */
  86.     switch(class){
  87.     case I:
  88.     case I+2:
  89.         ns = (control >> 1) & MMASK;
  90.     case S:    /* Note fall-thru */
  91.         nr = (control >> 5) & MMASK;
  92.         break;
  93.     }
  94.     /* This section follows the SDL diagrams by K3NA fairly closely */
  95.     switch(axp->state){
  96.     case LAPB_DISCONNECTED:
  97.         switch(type){
  98.         case SABM:    /* Initialize or reset link */
  99.             sendctl(axp,LAPB_RESPONSE,UA|pf);    /* Always accept */
  100.             clr_ex(axp);
  101.             axp->unack = axp->vr = axp->vs = 0;
  102.             lapbstate(axp,LAPB_CONNECTED);/* Resets state counters */
  103.             axp->srt = Axirtt;
  104.             axp->mdev = 0;
  105.             set_timer(&axp->t1,2*axp->srt);
  106.             start_timer(&axp->t3);
  107.             start_timer(&axp->t4);
  108.             break;
  109.         case DISC:    /* Always answer a DISC with a DM */
  110.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  111.             break;
  112.         case DM:    /* Ignore to avoid infinite loops */
  113.             break;
  114.         default:    /* All others get DM */
  115.             if(poll)
  116.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  117.             break;
  118.         }
  119.         if(axp->state == LAPB_DISCONNECTED){    /* we can close connection */
  120.             stop_timer(&axp->t1);    /* waste all the timers */
  121.             stop_timer(&axp->t3);
  122.             stop_timer(&axp->t4);
  123.             free_q(&axp->txq);    /* lose transmit queue */
  124.             del_ax25(axp);        /* clean out the trash */
  125.         }
  126.         break;
  127.     case LAPB_SETUP:
  128.         switch(type){
  129.         case SABM:    /* Simultaneous open */
  130.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  131.             break;
  132.         case DISC:
  133.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  134.             nr_derate(axp);
  135.             free_q(&axp->txq);
  136.             stop_timer(&axp->t1);
  137.             axp->reason = LB_DM;
  138.             lapbstate(axp,LAPB_DISCONNECTED);
  139.             break;
  140.         case UA:    /* Connection accepted */
  141.             /* Note: xmit queue not cleared */
  142.             stop_timer(&axp->t1);
  143.             start_timer(&axp->t3);
  144.             axp->unack = axp->vr = axp->vs = 0;
  145.             lapbstate(axp,LAPB_CONNECTED);
  146.             start_timer(&axp->t4);
  147.             break;
  148.         case DM:    /* Connection refused */
  149.             free_q(&axp->txq);
  150.             stop_timer(&axp->t1);
  151.             axp->reason = LB_DM;
  152.             lapbstate(axp,LAPB_DISCONNECTED);
  153.             break;
  154.         default:    /* Respond with DM only to command polls */
  155.             if(poll)
  156.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  157.             break;
  158.         }
  159.         break;
  160.     case LAPB_DISCPENDING:
  161.         switch(type){
  162.         case SABM:
  163.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  164.             break;
  165.         case DISC:
  166.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  167.             break;
  168.         case UA:
  169.         case DM:
  170.             stop_timer(&axp->t1);
  171.             lapbstate(axp,LAPB_DISCONNECTED);
  172.             break;
  173.         default:    /* Respond with DM only to command polls */
  174.             if(poll)
  175.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  176.             break;
  177.         }
  178.         break;
  179.     case LAPB_CONNECTED:
  180.         switch(type){
  181.         case SABM:
  182.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  183.             clr_ex(axp);
  184.             free_q(&axp->txq);
  185.             stop_timer(&axp->t1);
  186.             start_timer(&axp->t3);
  187.             axp->unack = axp->vr = axp->vs = 0;
  188.             lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  189.             break;
  190.         case DISC:
  191.             free_q(&axp->txq);
  192.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  193.             stop_timer(&axp->t1);
  194.             stop_timer(&axp->t3);
  195.             axp->reason = LB_NORMAL;
  196.             lapbstate(axp,LAPB_DISCONNECTED);
  197.             break;
  198.         case DM:
  199.             axp->reason = LB_DM;
  200.             lapbstate(axp,LAPB_DISCONNECTED);
  201.             break;
  202.         case UA:
  203.             est_link(axp);
  204.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */
  205.             break;
  206.         case FRMR:
  207.             est_link(axp);
  208.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  209.             break;
  210.         case RR:
  211.         case RNR:
  212.             axp->flags.remotebusy = (control == RNR) ? YES : NO;
  213.             if(poll)
  214.                 enq_resp(axp);
  215.             ackours(axp,nr);
  216.             break;
  217.         case REJ:
  218.             axp->flags.remotebusy = NO;
  219.             if(poll)
  220.                 enq_resp(axp);
  221.             ackours(axp,nr);
  222.             stop_timer(&axp->t1);
  223.             start_timer(&axp->t3);
  224.             /* This may or may not actually invoke transmission,
  225.              * depending on whether this REJ was caused by
  226.              * our losing his prior ACK.
  227.              */
  228.             inv_rex(axp);
  229.             break;
  230.         case I:
  231.             ackours(axp,nr); /** == -1) */
  232.             start_timer(&axp->t4);
  233.             if(len_p(axp->rxq) >= axp->window){
  234.                 /* Too bad he didn't listen to us; he'll
  235.                  * have to resend the frame later. This
  236.                  * drastic action is necessary to avoid
  237.                  * deadlock.
  238.                  */
  239.                 if(poll)
  240.                     sendctl(axp,LAPB_RESPONSE,RNR|pf);
  241.                 free_p(bp);
  242.                 bp = NULLBUF;
  243.                 break;
  244.             }
  245.             /* Reject or ignore I-frames with receive sequence number errors */
  246.             if(ns != axp->vr){
  247.                 if(axp->proto == V1 || !axp->flags.rejsent){
  248.                     axp->flags.rejsent = YES;
  249.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  250.                 } else if(poll)
  251.                     enq_resp(axp);
  252.                 axp->response = 0;
  253.                 break;
  254.             }
  255.             axp->flags.rejsent = NO;
  256.             axp->vr = (axp->vr+1) & MMASK;
  257.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  258.             if(poll){
  259.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  260.             } else {
  261.                 axp->response = tmp;
  262.             }
  263.             procdata(axp,bp);
  264.             bp = NULLBUF;
  265.             break;
  266.         default:    /* All others ignored */
  267.             break;
  268.         }
  269.         break;
  270.     case LAPB_RECOVERY:
  271.         switch(type){
  272.         case SABM:
  273.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  274.             clr_ex(axp);
  275.             stop_timer(&axp->t1);
  276.             start_timer(&axp->t3);
  277.             axp->unack = axp->vr = axp->vs = 0;
  278.             lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  279.             if(!run_timer(&axp->t4))
  280.                 start_timer(&axp->t4);
  281.             break;
  282.         case DISC:
  283.             free_q(&axp->txq);
  284.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  285.             stop_timer(&axp->t1);
  286.             stop_timer(&axp->t3);
  287.             axp->response = UA;
  288.             axp->reason = LB_NORMAL;
  289.             lapbstate(axp,LAPB_DISCONNECTED);
  290.             break;
  291.         case DM:
  292.             nr_derate(axp);
  293.             axp->reason = LB_DM;
  294.             lapbstate(axp,LAPB_DISCONNECTED);
  295.             break;
  296.         case UA:
  297.             est_link(axp);
  298.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */    
  299.             break;
  300.         case FRMR:
  301.             est_link(axp);
  302.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  303.             break;
  304.         case RR:
  305.         case RNR:
  306.             axp->flags.remotebusy = (control == RNR) ? YES : NO;
  307.             if(axp->proto == V1 || final){
  308.                 stop_timer(&axp->t1);
  309.                 ackours(axp,nr);
  310.                 if(axp->unack != 0){
  311.                     inv_rex(axp);
  312.                 } else {
  313.                     start_timer(&axp->t3);
  314.                     lapbstate(axp,LAPB_CONNECTED);
  315.                     if(!run_timer(&axp->t4))
  316.                         start_timer(&axp->t4);
  317.                 }
  318.             } else {
  319.                 if(poll)
  320.                     enq_resp(axp);
  321.                 ackours(axp,nr);
  322.                 /* Keep timer running even if all frames
  323.                  * were acked, since we must see a Final
  324.                  */
  325.                 if(!run_timer(&axp->t1))
  326.                     start_timer(&axp->t1);
  327.             }
  328.             break;
  329.         case REJ:
  330.             axp->flags.remotebusy = NO;
  331.             /* Don't insist on a Final response from the old proto */
  332.             if(axp->proto == V1 || final){
  333.                 stop_timer(&axp->t1);
  334.                 ackours(axp,nr);
  335.                 if(axp->unack != 0){
  336.                     inv_rex(axp);
  337.                 } else {
  338.                     start_timer(&axp->t3);
  339.                     lapbstate(axp,LAPB_CONNECTED);
  340.                     if(!run_timer(&axp->t4))
  341.                         start_timer(&axp->t4);
  342.                 }
  343.             } else {
  344.                 if(poll)
  345.                     enq_resp(axp);
  346.                 ackours(axp,nr);
  347.                 if(axp->unack != 0){
  348.                     /* This is certain to trigger output */
  349.                     inv_rex(axp);
  350.                 }
  351.                 /* A REJ that acks everything but doesn't
  352.                  * have the F bit set can cause a deadlock.
  353.                  * So make sure the timer is running.
  354.                  */
  355.                 if(!run_timer(&axp->t1))
  356.                     start_timer(&axp->t1);
  357.             }
  358.             break;
  359.         case I:
  360.             ackours(axp,nr); /** == -1) */
  361.             /* Make sure timer is running, since an I frame
  362.              * cannot satisfy a poll
  363.              */
  364.             if(!run_timer(&axp->t1))
  365.                 start_timer(&axp->t1);
  366.             if(len_p(axp->rxq) >= axp->window){
  367.                 /* Too bad he didn't listen to us; he'll
  368.                  * have to resend the frame later. This
  369.                  * drastic action is necessary to avoid
  370.                  * memory deadlock.
  371.                  */
  372.                 sendctl(axp,LAPB_RESPONSE,RNR | pf);
  373.                 free_p(bp);
  374.                 bp = NULLBUF;
  375.                 break;
  376.             }
  377.             /* Reject or ignore I-frames with receive sequence number errors */
  378.             if(ns != axp->vr){
  379.                 if(axp->proto == V1 || !axp->flags.rejsent){
  380.                     axp->flags.rejsent = YES;
  381.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  382.                 } else if(poll)
  383.                     enq_resp(axp);
  384.  
  385.                 axp->response = 0;
  386.                 break;
  387.             }
  388.             axp->flags.rejsent = NO;
  389.             axp->vr = (axp->vr+1) & MMASK;
  390.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  391.             if(poll){
  392.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  393.             } else {
  394.                 axp->response = tmp;
  395.             }
  396.             procdata(axp,bp);
  397.             bp = NULLBUF;
  398.             break;
  399.         default:
  400.             break;        /* Ignored */
  401.         }
  402.         break;
  403.     }
  404.     free_p(bp);    /* In case anything's left */
  405.  
  406.     /* See if we can send some data, perhaps piggybacking an ack.
  407.      * If successful, lapb_output will clear axp->response.
  408.      */
  409.     lapb_output(axp);
  410.     if(axp->response != 0){
  411.         sendctl(axp,LAPB_RESPONSE,axp->response);
  412.         axp->response = 0;
  413.     }
  414.     return 0;
  415. }
  416.  
  417. /* Handle incoming acknowledgements for frames we've sent.
  418.  * Free frames being acknowledged.
  419.  * Return -1 to cause a frame reject if number is bad, 0 otherwise
  420.  */
  421. static int
  422. ackours(axp,n)
  423. struct ax25_cb *axp;
  424. int16 n;
  425. {    
  426.     struct mbuf *bp;
  427.     int acked = 0;    /* Count of frames acked by this ACK */
  428.     int16 oldest;    /* Seq number of oldest unacked I-frame */
  429.     int32 rtt,abserr;
  430.  
  431.     /* Free up acknowledged frames by purging frames from the I-frame
  432.      * transmit queue. Start at the remote end's last reported V(r)
  433.      * and keep going until we reach the new sequence number.
  434.      * If we try to free a null pointer,
  435.      * then we have a frame reject condition.
  436.      */
  437.     oldest = (axp->vs - axp->unack) & MMASK;
  438.     while(axp->unack != 0 && oldest != n){
  439.         if((bp = dequeue(&axp->txq)) == NULLBUF){
  440.             /* Acking unsent frame */
  441.             return -1;
  442.         }
  443.         free_p(bp);
  444.         axp->unack--;
  445.         acked++;
  446.         if(axp->flags.rtt_run && axp->rtt_seq == oldest){
  447.             /* A frame being timed has been acked */
  448.             axp->flags.rtt_run = 0;
  449.             /* Update only if frame wasn't retransmitted */
  450.             if(!axp->flags.retrans){
  451.                 rtt = msclock() - axp->rtt_time;
  452.                 abserr = (rtt > axp->srt) ? rtt - axp->srt :
  453.                  axp->srt - rtt;
  454.  
  455.                 /* Run SRT and mdev integrators */
  456.                 axp->srt = ((axp->srt * 7) + rtt + 4) >> 3;
  457.                 axp->mdev = ((axp->mdev*3) + abserr + 2) >> 2;
  458.                 /* Update timeout */
  459.                 set_timer(&axp->t1,4*axp->mdev+axp->srt);
  460.             }
  461.         }
  462.         axp->flags.retrans = 0;
  463.         axp->retries = 0;
  464.         oldest = (oldest + 1) & MMASK;
  465.     }
  466.     if(axp->unack == 0){
  467.         /* All frames acked, stop timeout */
  468.         stop_timer(&axp->t1);
  469.         start_timer(&axp->t3);
  470.     } else if(acked != 0) { 
  471.         /* Partial ACK; restart timer */
  472.         start_timer(&axp->t1);
  473.     }
  474.     if(acked != 0){
  475.         /* If user has set a transmit upcall, indicate how many frames
  476.          * may be queued
  477.          */
  478.         if(axp->t_upcall != NULLVFP)
  479.             (*axp->t_upcall)(axp,axp->paclen * (axp->maxframe - axp->unack));
  480.     }
  481.     return 0;
  482. }
  483.  
  484. /* Establish data link */
  485. void
  486. est_link(axp)
  487. struct ax25_cb *axp;
  488. {
  489.     clr_ex(axp);
  490.     axp->retries = 0;
  491.     sendctl(axp,LAPB_COMMAND,SABM|PF);
  492.     stop_timer(&axp->t3);
  493.     start_timer(&axp->t1);
  494. }
  495. /* Clear exception conditions */
  496. static void
  497. clr_ex(axp)
  498. struct ax25_cb *axp;
  499. {
  500.     axp->flags.remotebusy = NO;
  501.     axp->flags.rejsent = NO;
  502.     axp->response = 0;
  503.     stop_timer(&axp->t3);
  504. }
  505. /* Enquiry response */
  506. static void
  507. enq_resp(axp)
  508. struct ax25_cb *axp;
  509. {
  510.     char ctl;
  511.  
  512.     ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  513.     sendctl(axp,LAPB_RESPONSE,ctl);
  514.     axp->response = 0;
  515.     stop_timer(&axp->t3);
  516. }
  517. /* Invoke retransmission */
  518. static void
  519. inv_rex(axp)
  520. struct ax25_cb *axp;
  521. {
  522.     axp->vs -= axp->unack;
  523.     axp->vs &= MMASK;
  524.     axp->unack = 0;
  525. }
  526. /* Send S or U frame to currently connected station */
  527. int
  528. sendctl(axp,cmdrsp,cmd)
  529. struct ax25_cb *axp;
  530. int cmdrsp;
  531. int cmd;
  532. {
  533.     if((ftype((char)cmd) & 0x3) == S)    /* Insert V(R) if S frame */
  534.         cmd |= (axp->vr << 5);
  535.     return sendframe(axp,cmdrsp,cmd,NULLBUF);
  536. }
  537. /* Start data transmission on link, if possible
  538.  * Return number of frames sent
  539.  */
  540. int
  541. lapb_output(axp)
  542. register struct ax25_cb *axp;
  543. {
  544.     register struct mbuf *bp;
  545.     struct mbuf *tbp;
  546.     char control;
  547.     int sent = 0;
  548.     int i;
  549.  
  550.     if(axp == NULLAX25
  551.      || (axp->state != LAPB_RECOVERY && axp->state != LAPB_CONNECTED)
  552.      || axp->flags.remotebusy)
  553.         return 0;
  554.  
  555.     /* Dig into the send queue for the first unsent frame */
  556.     bp = axp->txq;
  557.     for(i = 0; i < axp->unack; i++){
  558.         if(bp == NULLBUF)
  559.             break;    /* Nothing to do */
  560.         bp = bp->anext;
  561.     }
  562.     /* Start at first unsent I-frame, stop when either the
  563.      * number of unacknowledged frames reaches the maxframe limit,
  564.      * or when there are no more frames to send
  565.      */
  566.     while(bp != NULLBUF && axp->unack < axp->maxframe){
  567.         control = I | (axp->vs++ << 1) | (axp->vr << 5);
  568.         axp->vs &= MMASK;
  569.         dup_p(&tbp,bp,0,len_p(bp));
  570.         if(tbp == NULLBUF)
  571.             return sent;    /* Probably out of memory */
  572.         sendframe(axp,LAPB_COMMAND,control,tbp);
  573.         start_timer(&axp->t4);
  574.         axp->unack++;
  575.         /* We're implicitly acking any data he's sent, so stop any
  576.          * delayed ack
  577.          */
  578.         axp->response = 0;
  579.         if(!run_timer(&axp->t1)){
  580.             stop_timer(&axp->t3);
  581.             start_timer(&axp->t1);
  582.         }
  583.         sent++;
  584.         bp = bp->anext;
  585.         if(!axp->flags.rtt_run){
  586.             /* Start round trip timer */
  587.             axp->rtt_seq = (control >> 1) & MMASK;
  588.             axp->rtt_time = msclock();
  589.             axp->flags.rtt_run = 1;
  590.         }
  591.     }
  592.     return sent;
  593. }
  594. /* Set new link state */
  595. void
  596. lapbstate(axp,s)
  597. struct ax25_cb *axp;
  598. int s;
  599. {
  600.     int oldstate;
  601.  
  602.     oldstate = axp->state;
  603.     axp->state = s;
  604.     if(s == LAPB_DISCONNECTED){
  605.         stop_timer(&axp->t1);
  606.         stop_timer(&axp->t3);
  607.         stop_timer(&axp->t4);
  608.         free_q(&axp->txq);
  609.     }
  610.     /* Don't bother the client unless the state is really changing */
  611.     if((oldstate != s) && (axp->s_upcall != NULLVFP))
  612.         (*axp->s_upcall)(axp,oldstate,s);
  613. }
  614. /* Process a valid incoming I frame */
  615. static void
  616. procdata(axp,bp)
  617. struct ax25_cb *axp;
  618. struct mbuf *bp;
  619. {
  620.     int pid;
  621.     int seq;
  622.  
  623.     /* Extract level 3 PID */
  624.     if((pid = PULLCHAR(&bp)) == -1)
  625.         return;    /* No PID */
  626.  
  627.     if(axp->segremain != 0){
  628.         /* Reassembly in progress; continue */
  629.         seq = PULLCHAR(&bp);
  630.         if(pid == PID_SEGMENT
  631.          && (seq & SEG_REM) == axp->segremain - 1){
  632.             /* Correct, in-order segment */
  633.             append(&axp->rxasm,bp);
  634.             if((axp->segremain = (seq & SEG_REM)) == 0){
  635.                 /* Done; kick it upstairs */
  636.                 bp = axp->rxasm;
  637.                 axp->rxasm = NULLBUF;
  638.                 pid = PULLCHAR(&bp);
  639.                 handleit(axp,pid,bp);
  640.             }
  641.         } else {
  642.             /* Error! */
  643.             free_p(axp->rxasm);
  644.             axp->rxasm = NULLBUF;
  645.             axp->segremain = 0;
  646.             free_p(bp);
  647.         }
  648.     } else {
  649.         /* No reassembly in progress */
  650.         if(pid == PID_SEGMENT){
  651.             /* Start reassembly */
  652.             seq = PULLCHAR(&bp);
  653.             if(!(seq & SEG_FIRST)){
  654.                 free_p(bp);    /* not first seg - error! */
  655.             } else {
  656.                 /* Put first segment on list */
  657.                 axp->segremain = seq & SEG_REM;
  658.                 axp->rxasm = bp;
  659.             }
  660.         } else {
  661.             /* Normal frame; send upstairs */
  662.             handleit(axp,pid,bp);
  663.         }
  664.     }
  665. }
  666. /* New-style frame segmenter. Returns queue of segmented fragments, or
  667.  * original packet if small enough
  668.  */
  669. struct mbuf *
  670. segmenter(bp,ssize)
  671. struct mbuf *bp;    /* Complete packet */
  672. int16 ssize;        /* Max size of frame segments */
  673. {
  674.     struct mbuf *result = NULLBUF;
  675.     struct mbuf *bptmp,*bp1;
  676.     int16 len,offset;
  677.     int segments;
  678.  
  679.     /* See if packet is too small to segment. Note 1-byte grace factor
  680.      * so the PID will not cause segmentation of a 256-byte IP datagram.
  681.      */
  682.     len = len_p(bp);
  683.     if(len <= ssize+1)
  684.         return bp;    /* Too small to segment */
  685.  
  686.     ssize -= 2;        /* ssize now equal to data portion size */
  687.     segments = 1 + (len - 1) / ssize;    /* # segments  */
  688.     offset = 0;
  689.  
  690.     while(segments != 0){
  691.         offset += dup_p(&bptmp,bp,offset,ssize);
  692.         if(bptmp == NULLBUF){
  693.             free_q(&result);
  694.             break;
  695.         }
  696.         /* Make room for segmentation header */
  697.         if((bp1 = pushdown(bptmp,2)) == NULLBUF){
  698.             free_p(bptmp);
  699.             free_q(&result);
  700.             break;
  701.         }
  702.         bp1->data[0] = PID_SEGMENT;
  703.         bp1->data[1] = --segments;
  704.         if(offset == ssize)
  705.             bp1->data[1] |= SEG_FIRST;
  706.         enqueue(&result,bp1);
  707.     }
  708.     free_p(bp);
  709.     return result;
  710. }
  711.  
  712. static void
  713. handleit(axp,pid,bp)
  714. struct ax25_cb *axp;
  715. int pid;
  716. struct mbuf *bp;
  717. {
  718.     struct axlink *ipp;
  719.     int check_rose __ARGS((struct ax25_cb *axp));
  720.     extern int rose_enable;
  721.  
  722. #ifdef ROSE
  723.     if (rose_enable && pid == PID_NO_L3 && check_rose(axp))
  724.         pid = PID_IP;    /* replace PID removed by ROSE switch */
  725. #endif
  726.  
  727.     for(ipp = Axlink;ipp->funct != NULL;ipp++){
  728.         if(ipp->pid == pid)
  729.             break;
  730.     }
  731.     if(ipp->funct != NULL)
  732.         (*ipp->funct)(axp->iface,axp,NULLCHAR,NULLCHAR,bp,0);
  733.     else
  734.         free_p(bp);
  735. }
  736.  
  737. #ifdef ROSE
  738. /* test for rose connection via ax.25 */
  739.  
  740. int
  741. check_rose(axp)
  742. register struct ax25_cb *axp ;
  743. {
  744.     register int i ;
  745.     int addreq();
  746.     int found = 0 ;
  747.     struct ax_route *axr;
  748.  
  749.     if((axr = ax_lookup(axp->remote)) == NULLAXR)
  750.         return(FALSE);    /* probably can't happen */
  751.  
  752.     if(axr->ndigis < 2 || axr->ndigis > 4)
  753.         return(FALSE); /* can't be ROSE */
  754.  
  755.     for (i = 0 ;i<rosenbr_nr; i++)
  756.         if (addreq(rose_table[i].ipcall,axp->remote)) {
  757.             found = 1;
  758.             break;
  759.         }
  760.  
  761.     if(!found)
  762.         return(FALSE);
  763.                 /* neighbor ROSE address will normally be first
  764.                  * but sometimes second place */
  765.     if (addreq(rose_table[i].roscall,axr->digis[0]) ||
  766.                 /* now try least likely case where a digi was used
  767.                  * between rose and us
  768.                  */
  769.             addreq(rose_table[i].roscall,axr->digis[1]))
  770.         return(TRUE);
  771.  
  772.     return(FALSE);
  773. }
  774.  
  775. /*
  776.  * use: rose add IPcall Rosecall
  777.  */
  778.  
  779. static int
  780. rose_add(argc,argv)
  781. int argc;
  782. char *argv[];
  783. {
  784.     if(rosenbr_nr == ROSENUMCKTS - 1){
  785.         tprintf("Rose inbound circuit table full!\n");
  786.         return(-1);
  787.     }
  788.  
  789.     if(setcall(rose_table[rosenbr_nr].ipcall,argv[1]) == -1)  {
  790.         tprintf("IP Call ?\n");
  791.         return(-1);
  792.     }
  793.  
  794.     if(setcall(rose_table[rosenbr_nr].roscall,argv[2]) == -1)  {
  795.         tprintf("ROSE Call?\n");
  796.         return(-1);
  797.     }
  798.  
  799.     rosenbr_nr++;
  800.     rose_enable = TRUE;    /* convenient global flag */
  801.     return(0);
  802. }
  803.  
  804. static int
  805. rose_drop(argc,argv)
  806. int argc;
  807. char *argv[];
  808. {
  809.     int    i;
  810.     char    tmp[10];
  811.  
  812.         if(setcall(tmp, argv[1]) == -1) {
  813.                 printf("Call?\n");
  814.                 return(-1);
  815.         }
  816.  
  817.         for (i = 0; i < rosenbr_nr; i++)
  818.                 if (addreq(rose_table[i].ipcall, tmp))
  819.                         break;
  820.  
  821.         if (i == rosenbr_nr)
  822.                 return(-1);     /* wasn't in table */
  823.  
  824.         while (i<rosenbr_nr)  {
  825.                 memcpy(&rose_table[i].roscall,&rose_table[i+1].roscall,AXALEN);
  826.                 memcpy(&rose_table[i].ipcall,&rose_table[i+1].ipcall,AXALEN);
  827.                 i++;
  828.         }
  829.  
  830.     rosenbr_nr--;
  831.     if (!rosenbr_nr)
  832.         rose_enable = FALSE;
  833.  
  834.     return(0);
  835. }
  836.  
  837. /* "rose" subcommands */
  838.  
  839. static struct cmds rosecmds[] = {
  840.     "add", rose_add, 0, 3,
  841.     "add failed, or syntax error: rose add <dest IP call> <neighbor rose>",
  842.  
  843.     "drop", rose_drop, 0, 2,
  844.     "Not in table, or syntax error: rose drop <dest IP call>",
  845.  
  846.     NULLCHAR, NULLFP, 0, 0,
  847.     "rose subcommands: add, drop",
  848.     NULLCHAR
  849. };
  850.  
  851. /* Display and/or manipulate routing table */
  852.  
  853. int
  854. dorose(argc,argv)
  855. int argc;
  856. char *argv[];
  857. {
  858.     int    i;
  859.     char    tmp[10];
  860.  
  861.     if (argc < 2)  {
  862.         tprintf("Incoming Rose circuit table:\n");
  863.         if (!rosenbr_nr)  {
  864.             tprintf("(empty)\n");
  865.             return(0);
  866.         }
  867.  
  868.         for (i = 0; i < rosenbr_nr; i++)  {
  869.             pax25(tmp,rose_table[i].ipcall);
  870.             tprintf("IP Call: %s, ", tmp);
  871.             pax25(tmp,rose_table[i].roscall);
  872.             tprintf("ROSE: %s\n", tmp);
  873.         }
  874.  
  875.         return 0;
  876.     }
  877.  
  878.     return subcmd(rosecmds,argc,argv,NULLCHAR);
  879. }
  880. #endif    /* ROSE */
  881.